//
//	IOBUS - transport protocol
//
//  (c) 2008 mocom software GmbH & Co KG
//
//  $Author: volker $
//  $Date: 2009-10-01 18:51:54 +0200 (Do, 01. Okt 2009) $
//  $Revision: 509 $
//
//-------------------------------------------------------------------------------------------
//
#include <iobus.h>

IOBusObjectDir slavedir;

void IOBusSlave( IOBusFrame *frame )
{
	static UINT8 data[IOBUS_MAX_DATA_LENGTH];
	int len = 0;
	unsigned error = IO_ERR_Ok;
	unsigned cycle = frame->cycle;

	if ( frame->addr == 0xff )
	{
		// handle BC
		switch ( frame->cmdres )
		{
			case IO_CMD_EmStop:
				// set all output to off
				IOBusHalEMStop( &slavedir, cycle );
				break;

			case IO_CMD_Tick:
				// start sampling of IO
				IOBusHalStartCapture( &slavedir, cycle );
			default:
				break;
		}
	}
	else
	{
		// handle single cast
		switch ( frame->cmdres )
		{
			case IO_CMD_EmStop:
				// set all output to off
				IOBusHalEMStop( &slavedir, cycle );
				break;

			case IO_CMD_SysReadId:
				len = IOBusHalGetVersionString(&data[1]);
				len++;
				data[0] = slavedir.entries;
				break;

			case IO_CMD_Update:
				// read objects first
				len = IOBusObjectSerialize( &slavedir, ( IOBusObjectWireImage* )data, cycle, &error, OBJ_IS_INPUT );
				// ok, now write objects received -- if there are any
				if ( frame->len )
				{
					IOBusObjectDeSerialize( &slavedir, ( IOBusObjectWireImage* )frame->data, frame->cycle );
				}
				break;

			case IO_CMD_ReadInfo:
				len = IOBusObjectSerializeInfo( &slavedir, ( IOBusObjectWireImage* )data );
				break;

			case IO_CMD_ReadError:
				len = IOBusObjectSerializeError( &slavedir, ( IOBusObjectWireImage* )data );
				break;

			case IO_CMD_ReadStatistics:
				len = sizeof( IOBusStatistics );
				IOBusHalMemoryCopy( data, ( void* )IOBusGetStatisticsPtr(), len );
			default:
				break;
		}
		IOBusSendCmd( frame->addr, error, cycle, len, data );
	}
}
